Skip to content

prune merged branches#94

Merged
skarim merged 8 commits into
skarim/rebase-docsfrom
skarim/prune-merged-branches
May 15, 2026
Merged

prune merged branches#94
skarim merged 8 commits into
skarim/rebase-docsfrom
skarim/prune-merged-branches

Conversation

@skarim
Copy link
Copy Markdown
Collaborator

@skarim skarim commented May 15, 2026

Prune merged branches during sync

Add a --prune flag to gh stack sync that deletes local branches (and their remote-tracking refs) for merged PRs. In interactive terminals, users are prompted if they would like to prune merged branches. Non-interactive sessions (agents) require the explicit flag.

Changes

  • Prune flag (cmd/sync.go): New --prune flag deletes local branches for merged PRs. Deletes both the local branch (git branch -D) and the remote-tracking ref (git branch -dr) so git checkout can't resurrect the branch. If the user is on a pruned branch, checkout moves to the nearest active branch or trunk.
  • Interactive prompt (cmd/sync.go): When --prune is not set and the terminal is interactive, prompts "Prune N merged branches?" with default yes. Skipped entirely in non-interactive sessions.
  • ConfirmFn hook (internal/config/config.go): New test hook following the existing SelectFn pattern — allows tests to inject mock confirm responses.
  • DeleteTrackingRef (internal/git): New git operation to delete local remote-tracking refs (git branch -dr origin/<branch>).
  • TUI merged-branch guards (internal/tui/stackview, internal/tui/modifyview): Merged branches can no longer be selected via keyboard navigation, mouse click, or Enter/checkout in either the view or modify TUI. Cursor skips over merged nodes.
  • Stack API fix (cmd/submit.go): Include merged PRs in the PUT payload to the stacks API — omitting them caused "Stack contents have changed" rejections on partially-merged stacks.

Stack created with GitHub Stacks CLIGive Feedback 💬

@skarim skarim force-pushed the skarim/prune-merged-branches branch from a309b6a to d985618 Compare May 15, 2026 14:25
@skarim skarim marked this pull request as ready for review May 15, 2026 15:38
Copilot AI review requested due to automatic review settings May 15, 2026 15:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an optional “prune merged branches” flow to gh stack sync, including a new --prune flag and an interactive confirmation prompt (interactive only). Also updates TUI behavior to prevent interacting with merged branches and fixes stack API syncing to include merged PRs so partially-merged stacks don’t get rejected.

Changes:

  • Add gh stack sync --prune to delete local merged branches and their remote-tracking refs, with interactive confirmation when the flag isn’t provided.
  • Add ConfirmFn test hook and a new git op (DeleteTrackingRef) to support pruning behavior and testing.
  • Harden TUI navigation/selection against merged nodes and include merged PRs in stack API update payloads.
Show a summary per file
File Description
skills/gh-stack/SKILL.md Documents gh stack sync --prune usage in the skill guide.
README.md Adds --prune flag docs and mentions interactive pruning behavior.
docs/src/content/docs/reference/cli.md Updates CLI reference docs for the new prune step/flag.
docs/src/content/docs/guides/workflows.md Notes pruning as an additional sync step (with --prune).
docs/src/content/docs/guides/stacked-prs.md Mentions optional pruning as part of sync behavior.
cmd/sync.go Implements --prune, interactive confirm prompt, branch switching, and pruning operations.
cmd/sync_test.go Adds extensive coverage for prune flows (flagged, interactive confirm, switching behavior, failures).
internal/config/config.go Adds ConfirmFn hook for tests to override confirm prompting.
internal/git/gitops.go Extends git ops interface + default implementation with DeleteTrackingRef.
internal/git/git.go Exposes DeleteTrackingRef via package-level wrapper.
internal/git/mock_ops.go Extends git mock with DeleteTrackingRefFn + method implementation.
internal/tui/stackview/model.go Prevents cursor/checkout/mouse selection of merged branches; cursor skips merged nodes.
internal/tui/stackview/model_test.go Adds tests verifying cursor initialization/navigation skips merged nodes and enter guard.
internal/tui/modifyview/model.go Makes modify TUI cursor movement skip merged branches; blocks mouse selection of merged nodes.
internal/tui/modifyview/model_test.go Adds cursor navigation test for merged-node skipping in modify view.
cmd/submit.go Includes merged PRs in stack API PUT payload to avoid “Stack contents have changed” rejections.
cmd/submit_test.go Updates test expectation to require merged PRs included in payload.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (2)

internal/tui/stackview/model.go:242

  • The merged-branch guard returns early before handling result.OpenURL (and toggles), which prevents users from clicking PR/commit/file links on merged branches. If the intent is only to prevent selecting/checkout, consider still honoring OpenURL (and possibly expand/collapse) while skipping cursor movement/selection for merged nodes.
	// Don't allow selecting merged branches.
	if m.nodes[result.NodeIndex].Ref.IsMerged() {
		return m, nil
	}

	m.cursor = result.NodeIndex

	if result.OpenURL != "" {
		shared.OpenBrowserInBackground(result.OpenURL)
	}

internal/tui/modifyview/model.go:882

  • The merged-branch guard returns early before processing result.OpenURL (and toggles), which prevents clicking PR/commit/file links on merged branches. If merged branches should only be non-selectable, consider still honoring OpenURL (and optionally toggles) while skipping cursor selection.
	// Don't allow selecting merged branches.
	if m.nodes[result.NodeIndex].Ref.IsMerged() {
		return m, nil
	}

	m.cursor = result.NodeIndex

	if result.OpenURL != "" {
		shared.OpenBrowserInBackground(result.OpenURL)
	}
  • Files reviewed: 17/17 changed files
  • Comments generated: 3

Comment thread cmd/sync.go
Comment thread cmd/sync.go Outdated
Comment thread cmd/sync.go Outdated
Copy link
Copy Markdown

@ktravers ktravers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The skip/include merged branches changes seem like they could be their own separate PR, but I might be misunderstanding the connection between those and pruned branches 🤷‍♀️

Otherwise looks good, appreciate the solid test coverage and documentation as always ✨ 🚀

@skarim skarim merged commit d3be1b5 into main May 15, 2026
6 checks passed
@skarim skarim deleted the skarim/prune-merged-branches branch May 15, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants